package pikes.ecma;

import java.io.IOException;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import pikes.ecma.EcmaSyntaxVisitingException;
import pikes.ecma.FunctionDeclaration;
import pikes.ecma.SourceElement;
import pikes.ecma.SyntaxTreeVisitor;

public class FunctionDeclarationTestCase {

	private MockSyntaxTreeVisitor syntaxTreeVisitor = null;

	private StringBuilder appendable = null;

	@Before
	public void setup() {
		appendable = new StringBuilder();
		syntaxTreeVisitor = new MockSyntaxTreeVisitor();
	}

	@Test
	public void visitEmptyFunctionDeclaration() throws Exception {
		FunctionDeclaration fd = new FunctionDeclaration("go");
		fd.visit(syntaxTreeVisitor);

		Assert.assertTrue(syntaxTreeVisitor.isFunction);
		Assert.assertTrue(syntaxTreeVisitor.isWhiteSpace);
		Assert.assertTrue(syntaxTreeVisitor.identifier.equals("go"));

		Assert.assertTrue(syntaxTreeVisitor.isBeforeParameterList);
		Assert.assertTrue(syntaxTreeVisitor.isAfterParameterList);

		Assert.assertTrue(syntaxTreeVisitor.isBeforeFunctionBody);
		Assert.assertTrue(syntaxTreeVisitor.isAfterFunctionBody);
	}

	@Test
	public void printEmptyFunctionDeclaration() throws Exception {
		FunctionDeclaration fd = new FunctionDeclaration("go");
		fd.print(appendable);

		Assert.assertEquals("function go(){}", appendable.toString());
	}

	@Test
	public void printEmptyFunctionDeclarationWithFormalParameterList() throws Exception {
		FunctionDeclaration fd = new FunctionDeclaration("go");
		fd.add("country1");
		fd.print(appendable);

		Assert.assertEquals("function go(country1){}", appendable.toString());
	}

	@Test
	public void visitEmptyFunctionDeclarationWithFormalParameterList() throws Exception {
		FunctionDeclaration fd = new FunctionDeclaration("go");
		fd.add("country1");

		fd.visit(syntaxTreeVisitor);

		Assert.assertTrue(syntaxTreeVisitor.isFunction);
		Assert.assertTrue(syntaxTreeVisitor.isWhiteSpace);
		Assert.assertTrue(syntaxTreeVisitor.isBeforeParameterList);
		Assert.assertTrue(syntaxTreeVisitor.identifier.equals("country1"));
		Assert.assertTrue(syntaxTreeVisitor.isAfterParameterList);
		Assert.assertTrue(syntaxTreeVisitor.isBeforeFunctionBody);
		Assert.assertTrue(syntaxTreeVisitor.isAfterFunctionBody);
	}

	@Test
	public void visitNonEmptyFunctionDeclaration() throws Exception {
		FunctionDeclaration fd = new FunctionDeclaration("go");
		SourceElement mockSourceElement = new SourceElement() {

			public void visit(SyntaxTreeVisitor syntaxTreeVisitor) throws EcmaSyntaxVisitingException {
				syntaxTreeVisitor.visitSourceElement(this);
			}

			public void print(Appendable arg0) throws IOException {
				// TODO Auto-generated method stub

			}

		};
		fd.add(mockSourceElement);
		fd.visit(syntaxTreeVisitor);

		Assert.assertTrue(syntaxTreeVisitor.isFunction);
		Assert.assertTrue(syntaxTreeVisitor.isWhiteSpace);
		Assert.assertTrue(syntaxTreeVisitor.identifier.equals("go"));
		Assert.assertTrue(syntaxTreeVisitor.isBeforeParameterList);
		Assert.assertTrue(syntaxTreeVisitor.isAfterParameterList);
		Assert.assertTrue(syntaxTreeVisitor.isBeforeFunctionBody);
		Assert.assertSame(mockSourceElement, syntaxTreeVisitor.sourceElement);
		Assert.assertTrue(syntaxTreeVisitor.isAfterFunctionBody);
	}
}
